<?php

namespace App\Http\Controllers\Admin;

use App\Exceptions\AppException;
use App\Models\Answer;
use App\Models\Config;
use App\Models\Data;
use App\Models\Member;
use App\Models\MemberAnswer;
use App\Models\MemberDay;
use App\Models\MemberQrcode;
use App\Models\MemberRecord;
use App\Models\Organization;
use App\Models\OrganizationSubject;
use App\Models\Problem;
use App\Models\Question;
use App\Models\QuestionMember;
use App\Models\Subject;
use App\Models\Url;
use App\Services\ExcelExportService;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Storage;
use SimpleSoftwareIO\QrCode\Facades\QrCode;
use function GuzzleHttp\Psr7\str;

class MemberController extends BaseController {

    /**
     *
     * @param Request $request
     * @return array
     */
    public function index(Request $request)
    {
        $params = $request->all();

        $build = Member::query()->select(['member_id', 'code', 'status', 'record_code', 'name', 'mobile']);
        if (isset($params['name'])){
            $name = $params['name'];
            $build->where('name', 'like', "%$name%");
        }
            $build->orderBy('member_id', 'desc');
        $pageSize = $request->input('pageSize', 50);
        $data = $build->paginate($pageSize)->toArray();
        return $this->success($data);
    }

    /**
     * @param Request $request
     * @return array
     */
    public function import(Request $request)
    {
        //在源生的php代码中是使用$_FILE来查看上传文件的属性
        //但是在laravel里面有更好的封装好的方法，就是下面这个
        //显示的属性更多
        $fileCharater = $request->file('file');
        $success_num = $error_num = 0;
        try {

            if ($fileCharater->isValid()) { //括号里面的是必须加的哦
                //如果括号里面的不加上的话，下面的方法也无法调用的

                //获取文件的扩展名
                $ext = $fileCharater->getClientOriginalExtension();

                if (!in_array($ext, ['xlsx', 'xls'])){
                    throw new AppException('import_type_is_fail');
                }

                //获取文件的绝对路径
                $path = $fileCharater->getRealPath();

                //定义文件名
                $filename = date('Y-m-d-H-i-s').'.'.$ext;

                //存储文件。disk里面的public。总的来说，就是调用disk模块里的public配置
                Storage::disk('public')->put($filename, file_get_contents($path));

                $directory = storage_path('app') . '/public';

                $reader = \PhpOffice\PhpSpreadsheet\IOFactory::createReader('Xlsx');
                # 打开文件、载入excel表格
                $spreadsheet = $reader->load($directory . '/' . $filename);
                # 获取活动工作薄
                $sheet = $spreadsheet->getActiveSheet();

                # 获取总列数
                $highestColumn = $sheet->getHighestColumn();
                # 获取总行数
                $highestRow = $sheet->getHighestRow();
                # 列数 改为数字显示
                $highestColumnIndex = \PhpOffice\PhpSpreadsheet\Cell\Coordinate::columnIndexFromString($highestColumn);

                for($a = 2;$a <= $highestRow; $a++){
                    $i = 0;
                    $name = $sheet->getCellByColumnAndRow(1,$a)->getValue();
//                    $mobile = $sheet->getCellByColumnAndRow(2,$a)->getValue();
                    $code = $sheet->getCellByColumnAndRow(2,$a)->getValue();
                    $organ = $sheet->getCellByColumnAndRow(3,$a)->getValue();
                    $row_data = [];
                    for ($column = 1; $column <= $highestColumnIndex; $column++) {
                        $row_data[] = $sheet->getCellByColumnAndRow($column, $a)->getValue();
                        $i++;
                    }
                    if(!implode('',$row_data)){
                        //删除空行
                        continue;
                    }

                    $resultOrg = Organization::query()->firstOrCreate(
                        ['organization_name' => $organ]
                    );


                    $exist = OrganizationSubject::query()->where('organization_id', $resultOrg->organization_id)->first();
                    if (!$exist){
                        OrganizationSubject::query()->firstOrCreate(
                            [
                                'organization_id' => $resultOrg->organization_id,
                                'organization_name' => $organ
                            ]
                        );
                    }
                    $data = [
                        'name' => $name,
//                        'mobile' => $mobile,
                        'code' => $code,
                        'organization_id' => $resultOrg->organization_id,
                    ];

                    $result = Member::query()->create($data);
                    if ($result){
                        $success_num = $success_num +1;
                    }else{
                        $error_num = $error_num + 1;
                    }
                }
            }
            $data['success_num'] = $success_num;
            $data['error_num'] = $error_num;
            return $this->success($data);

        } catch (\ Exception $exception) {
            throw new AppException($exception->getMessage());

        }

    }


    public function destroy($memberId, Request $request)
    {
        $memberData = Member::query()->where('member_id', $memberId)->first();

        if (!$memberData){
            throw new AppException('find_member_is_fail');
        }

        $result = $memberData->delete();
        return $this->success($result, '删除成功');

    }

    public function getMemberRole($data)
    {
        if ($data['team_info'] == ''){
            return Member::team;
        }
        if ($data['rm_info'] == ''){
            return Member::rm;
        }
        if ($data['dm_info'] == ''){
            return Member::dm;
        }
        return Member::mr;
    }

    /**
     * 导出excel
     * @param Request $request
     * @return \Symfony\Component\HttpFoundation\BinaryFileResponse
     * @throws AppException
     */
    public function export(Request $request)
    {
        try {
            $directory = storage_path();
            $fileName = rand(1000, 9999) . time() . ".xlsx";//导出文件名
            $header = [
                'name' => '姓名', 'code' => '工号','organization_name' => '部门',  'score' => '成绩',
            ];

            $widthArray = ['A' => 10, 'B' => 10, 'C' => 10, 'D' => 10, 'E' => 10];
            $build = Member::query()
                ->select(['code', 'name', 'organization_name', 'score'])
                ->leftJoin('ty_organization', 'ty_organization.organization_id', '=', 'ty_member.organization_id')
            ->get()->toArray();
            $service = new ExcelExportService();
            $service->exportDataArrayBySheet($directory, $fileName, $build, $header, '', 2000, $widthArray);
            return response()->download($directory . '/' . $fileName, '导出文件.xlsx', $headers = ['Content-Type' => 'application/zip;charset=utf-8']);
        } catch (\ Exception $exception) {
            echo $exception->getMessage();die;
            throw new AppException('export_fail');
        }
    }

    public function dataExport()
    {

        $member = Member::query()->get()->toArray();
        $result = [];
        foreach ($member as $keys => $values){
            $json = $values['content'];
            if ($json == ''){
                continue;
            }

            $arr = \GuzzleHttp\json_decode($json, true);

            $resultData = [];
            $header = ['code' => 'nickname', 'record_code' => '编码', 'name' => '标签', 'status' => '是否核销'];
            foreach ($arr as $key => $value){
                $col = 'p'. $key;
                $header[$col] = $value['timu'];
                $resultData[$col] = $value['true_answer'];
                $resultData['code'] = $values['mobile'];
                $resultData['record_code'] = " ". strval($values['record_code']) . " ";
                $resultData['name'] = $values['name'];
                if ($values['status'] == '2'){
                    $str = '是';
                }else{
                    $str = '否';
                }
                $resultData['status'] = $str;
            }
            $result[] = $resultData;
        }


        try {
            $directory = storage_path();
            $fileName = rand(1000, 9999) . time() . ".xlsx";//导出文件名

            $widthArray = ['A' => 10, 'B' => 40, 'C' => 10, 'D' => 10, 'E' => 10];
            $service = new ExcelExportService();
            $service->exportDataArrayBySheet($directory, $fileName, $result, $header, '', 2000, $widthArray);
            return response()->download($directory . '/' . $fileName, '导出文件.xlsx', $headers = ['Content-Type' => 'application/zip;charset=utf-8']);
        } catch (\ Exception $exception) {
            echo $exception->getMessage();die;
            throw new AppException('export_fail');
        }
    }


    public function memberAnswer(Request $request)
    {
        $params = $request->all();

        if (!isset($params['member_id'])){
            return $this->errorCode('10001', [], '请填写code');
        }

        if (!isset($params['content'])){
            return $this->errorCode('10001', [], '请填写答题记录');
        }

        if (!isset($params['status'])){
            return $this->errorCode('10001', [], 'status必传');
        }


        $result = Member::query()->where('member_id', $params['member_id'])->update([
            'content' => $params['content'],
            'status' => $params['status'],
        ]);

        if ($params['status'] == 1){
            //生成二维码

            MemberRecord::query()->create(
                [
                    'member_id' => $params['member_id'],
                    'add_time' => time()
                ]
            );

            $sn = date('Y', time());
            $sn.= date('m', time());
            $sn.= date('d', time());
            $today = strtotime(date("Y-m-d"),time());

            $all = MemberRecord::query()->where('add_time', '>', $today)->get();

            $num = 1000;

            $num = $num + count($all);

            $num = substr($num, 1);
            $num = $sn . 0 . $num;

            Member::query()->where('member_id', $params['member_id'])->update([
                'record_code' => $num,
            ]);

            $disk = Storage::disk('public');//获取磁盘实例
            $url = "http://me.amrtang.com/hx-yywenjuan?qrcode=true&member_id=" . $params['member_id'];
            $img = $params['member_id'] . ".png";
            $result = $disk->delete($img);//删除一个
            QrCode::encoding('UTF-8')->format('png')->size(500)->margin(0)->generate($url , public_path('/'.$img));
        }
        return $this->success($result, '保存成功');

    }

    public function qrCodeList(Request $request)
    {
        $result = MemberQrcode::query()->get();
        return $this->success($result, '保存成功');
    }


    /**
     * @param Request $request
     * @return array
     */
    public function authGetOpenId(Request $request)
    {

        $params = $request->all();
        if (!isset($params['code'])){
            return $this->errorCode('10001', [], '请填写code');
        }

        if (!isset($params['source'])){
            return $this->errorCode('10001', [], '请填写source');
        }

        $code = $params['code'];
        $source = $params['source'];
        $str = 'https://api.weixin.qq.com/sns/oauth2/access_token?appid=wx9317c76251b85714&secret=094682f1ecd518b10c801b8a22aae318&code='. $code . '&grant_type=authorization_code';
        $response = $this->geturl($str);
        if (!isset($response['openid'])){
            return $this->errorCode('10001', [], '微信id获取失败');
        }

        $openId = $response['openid'];
        $access_token = $response['access_token'];

        $str2 = "https://api.weixin.qq.com/sns/userinfo?access_token=$access_token&openid=$openId&lang=zh_CN";
        $response2 = $this->geturl($str2);
        //生成member数据

        $member = Member::query()->where('code', $openId)->first();
        if ($member){
            if ($member['status'] == 0 ){
                Member::query()->where('code', $openId)->update(['name' => $source]);
            }
            $member = Member::query()->where('code', $openId)->first();
            return $this->success($member, '获取成功');
        }else{
            $member = Member::query()->create([
                'code' => $openId,
                'name' => $source,
                'mobile' => $response2['nickname']
            ]);
            return $this->success($member, '获取成功');
        }
    }

    function geturl($url){
        $headerArray =array("Content-type:application/json;","Accept:application/json");
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($ch,CURLOPT_HTTPHEADER,$headerArray);
        $output = curl_exec($ch);
        curl_close($ch);
        $output = json_decode($output,true);
        return $output;
    }

    public function login($id, Request $request)
    {
        $member = Member::query()
            ->where('member_id', $id)
            ->first();
        return $this->success($member);
    }

    /**
     * 工作人眼核销
     */
    public function heXiao($id, Request $request)
    {
        $params = $request->all();
        $data = Member::query()->where('member_id', $id)->first();
        if (!$data){
            return $this->errorCode('10001', [], '用户信息获失败');
        }

        $config = Config::query()->first()->toArray();
        if ($params['password'] != $config['password']){
            return $this->errorCode('10001', [], '核销密码错误，请重新输入');
        }
        $data = $data->toArray();
        if ($data['status'] == 2){
            return $this->errorCode('10001', [], '您已经核销过，请勿重复核销');
        }

        $result = Member::query()->where('member_id', $id)->update(['status' => 2]);
        return $this->success($result, '核销成功');
    }

    /**
     * 更新密码
     * @param Request $request
     * @return array
     */
    public function savePassword(Request $request)
    {
        $params = $request->all();
        $result = Config::query()->where('id', 1)->update(['password' => $params['password']]);
        return $this->success($result);
    }

    public function addQrcode(Request $request)
    {

        $params = $request->all();
        if (!isset($params['name'])){
            return $this->errorCode('10001', [], '问卷标签为空');
        }
        $qrcode = time() . '.png';
        $redirect_uri = 'http://me.amrtang.com/yywenjuan?source=' . $params['name'];
        $url = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=wx9317c76251b85714&redirect_uri=$redirect_uri&response_type=code&scope=snsapi_userinfo&state=123#wechat_redirect";
        QrCode::encoding('UTF-8')->format('png')->size(500)->generate($url ,public_path('/'.$qrcode));

        $result = MemberQrcode::query()->create([
            'name' => $params['name'],
            'url' => $url,
            'qrcode' => $qrcode
        ]);
        return $this->success($result);
    }

    public function update($id, Request $request)
    {
        $params = $request->all();
        unset($params['token']);
        $data = Member::query()->where('member_id', $id)->first();
        if (!$data){
            throw new AppException('find_member_is_fail');
        }

        unset($params['member_id']);
        $updateParams  = [];
        $updateParams['province'] = $params['province'];
        $updateParams['mobile'] = $params['mobile'];
        $updateParams['name'] = $params['name'];
        $updateParams['hospital'] = $params['hospital'];
        $updateParams['department'] = $params['department'];
        $result = Member::query()->where('member_id', $id)->update($updateParams);
        return $this->success($result, '修改成功');
    }

    public function memberAdd(Request $request)
    {
        $params = $request->all();
        unset($params['token']);
        $data = Member::query()->where('name', $params['name'])->first();
        if (!isset($params['code'])){
            return $this->errorCode('10001', [], '请填写区域');
        }

        if ($data){

            return $this->success($data, '注册成功');
        }else{

            $result = Member::query()->create($params);
            return $this->success($result, '注册成功');
        }
    }

    public function MemberInfo($id, Request $request)
    {
        $result = Member::query()->where('member_id', $id)->first()->toArray();
        $result['subject_name'] = '';
        $subject_name = Subject::query()->where('sid', $result['last_subject_id'])->first();
        if($subject_name){
            $result['subject_name'] = $subject_name['name'];
        }

        return $this->success($result, '获取成功');
    }

    public function rank($id, Request $request)
    {
        $params = $request->all();
        $num = $params['num'];
        $result = Member::query()->orderBy('all_score', 'desc')->limit($num)->get()->toArray();

        //查看 自己是第几名
        $member = Member::query()->where('member_id', $id)->first()->toArray();
        $resultAll = Member::query()->where('all_score', '>', $member['all_score'])->get()->toArray();
        return $this->success(['data' =>$result, 'rank' => count($resultAll) + 1], '获取成功');
    }

    public function indexConfig(Request $request)
    {
        $config = Config::query()->where('id' , 1)->first();
        return $this->success($config, '获取成功');

    }

    public function updateConfig($id, Request $request)
    {
        $params = $request->all();
        if (!isset($params['date']) || empty($params['date'])){
            return $this->errorCode('10001', [], '请填写时间');
        }
        if (!isset($params['spend_time']) || empty($params['spend_time'])){
            return $this->errorCode('10001', [], '请填写考试时长');
        }
        $old = Config::query()->where('id', 1)->first()->toArray();
        if (isset($params['status']) ){
            $data['status'] = $params['status'];
            if ($params['status'] == 1 && $old['status'] != 1){
                $data['num'] = $old['num'] + 1;

                //开启后清空答题数据

                MemberAnswer::query()->delete();

                Member::query()->update(['score' => 0]);

            }
        }
        $date = $params['date'];

        $data['date'] = $date;
        $data['spend_time'] = $params['spend_time'];

        $result = Config::query()->where('id', 1)->update($data);
        return $this->success($result, '更新成功');

    }

    public function indexUrl(Request $request)
    {
        $config = Url::query()->where('id' , 1)->first();
        return $this->success($config, '获取成功');

    }

    public function updateUrl($id, Request $request)
    {
        $params = $request->all();
        $url = $params['url'];
        $result = Url::query()->where('id', 1)->update(['url'=> $url]);
        return $this->success($result, '更新成功');

    }

    public function receive($id, Request $request)
    {
        $params = $request->all();
        if (!isset($params['type'])){
            return $this->errorCode('10001', [], '参数错误领取失败');
        }
        $type = $params['type'];
        if ($type == 1){
            //1500奖品
            $result = Member::query()->where('member_id', $id)->update(['one_status'=> Member::STATUS_TWO]);


        }elseif ($type == 2){
            $result = Member::query()->where('member_id', $id)->update(['two_status'=> Member::STATUS_TWO]);

            //4500奖品
        }else{
            //100道题领取
            $result = Member::query()->where('member_id', $id)->update(['hundred_reward'=> 1]);

        }
        return $this->success($result, '更新成功');
    }


    public function achievementList(Request $request)
    {
        $params = $request->all();
        if (!isset($params['type'])){
            return $this->errorCode('10001', [], '参数错误');
        }

        $result = [];
        if ($params['type'] == 1){
            //答题满100的 客户列表
            $result = Member::query()->where('num', '>=', 20)->get();

        }elseif ($params['type'] == 2){
            //达到1500分
            $result = Member::query()->where('all_score', '>=', 1500)->get();

        }elseif ($params['type'] ==3){
            //达到4500分
            $result = Member::query()->where('all_score', '>=', 4500)->get();
        }else{

        }
        return $this->success($result, '获取成功');
    }

    public function achieveDay($id, Request $request)
    {
        $params = $request->all();

        $day = MemberDay::query()->where('member_id', $id)->where('date', $params['date'])->first();
        if ($day)
        {
            return $this->errorCode('10001', [], '当天已经点亮，请勿重复操作');
        }
        $result = MemberDay::query()->create([
            'member_id' => $id,
            'date' => $params['date']
        ]);
        return $this->success($result, '');
    }

    public function updateMemberLast($id, Request $request)
    {
        $params = $request->all();

        $Member = Member::query()->where('member_id', $id)->first();
        if (!$Member)
        {
            return $this->errorCode('10001', [], '此用户不存在。请联系管理员');
        }

        if (!isset($params['last_subject_id'])){
            return $this->errorCode('10001', [], '请填写题库信息');
        }

        $subject = Subject::query()->where('sid', $params['last_subject_id'])->first();

        if (!$subject){
            return $this->errorCode('10001', [], '题库信息错误');
        }
        if (!isset($params['last_question_id'])){
            return $this->errorCode('10001', [], '请填写问题信息');
        }
//
//        $subject = Problem::query()->where('pid', $params['last_question_id'])->first();
//
//        if (!$subject){
//            return $this->errorCode('10001', [], '问题信息有误');
//        }

        $result = Member::query()->where('member_id', $id)->update([
            'last_subject_id' => $params['last_subject_id'],
            'last_question_id' => $params['last_question_id'],
        ]);
        return $this->success($result, '更新成功');

    }

    /**
     * @param $id
     * @param Request $request
     * @return \Symfony\Component\HttpFoundation\BinaryFileResponse
     * @throws AppException
     */
    public function exportMemberAnswer($id, Request $request)
    {
        $params = $request->all();
        try {
            $directory = storage_path();
            $fileName = rand(1000, 9999) . time() . ".xlsx";//导出文件名
            $header = [
                'name' => '姓名', 'content' => '题目','member_answer_data' => '答案',  'created_at' => '答题时间',
            ];
            $config = Config::query()->where('id', 1)->first()->toArray();

            $widthArray = ['A' => 10, 'B' => 10, 'C' => 10, 'D' => 10, 'E' => 10];
            $build = MemberAnswer::query()->leftJoin('ty_member', 'ty_member.member_id', '=', 'ty_member_answer.uid')
                ->leftJoin('ty_problem', 'ty_problem.pid', '=', 'ty_member_answer.pid');
            if ($params['type'] == 2){
                $build->where('ty_member_answer.uid', $id);
            }
            $result = $build->get()->toArray();
            foreach ($result as $key => $value){
                $answerContent = '';
                if ($value['member_answer'] != ''){
                    $thisAnswer = Answer::query()->whereIn('aid', explode(',', $value['member_answer']))->pluck('content')->toArray();
                    $answerContent = implode(',', $thisAnswer);
                }
                $result[$key]['member_answer_data'] = $answerContent;
            }

            $service = new ExcelExportService();
            $service->exportDataArrayBySheet($directory, $fileName, $result, $header, '', 2000, $widthArray);
            return response()->download($directory . '/' . $fileName, '导出文件.xlsx', $headers = ['Content-Type' => 'application/zip;charset=utf-8']);
        } catch (\ Exception $exception) {
            echo $exception->getMessage();die;
            throw new AppException('export_fail');
        }
    }

    public function getMemberHaveAnswer($id, Request $request)
    {
        $params = $request->all();
        $result = MemberAnswer::query()
            ->where('uid', $id)
            ->where('num', $params['num'])->first();
        $data = false;
        if ($result){
            $data = true;
        }
        return $this->success($data, '获取成功');
    }

    /**
     * 处理小数点
     * @param $data
     * @param $number
     * @return false|string
     */
    function formatDecimal($data, $number)
    {
        $data = $data * 100;
        $pos = stripos((string)$data, '.');
        return substr((string)$data, 0, $pos + $number + 1);
    }




}
